package com.victor.core.intercept;

import com.victor.common.constant.Const;
import com.victor.common.constant.Magic;
import com.victor.common.constant.factory.ConstantFactory;
import com.victor.common.constant.state.ManagerStatus;
import com.victor.common.controller.BaseController;
import com.victor.common.persistence.model.User;
import com.victor.core.shiro.ShiroKit;
import com.victor.core.support.HttpKit;
import com.victor.core.util.ToolUtil;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.session.InvalidSessionException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 验证session超时的拦截器
 */
@Aspect
@Component
@ConditionalOnProperty(prefix = "victor", name = "session-open", havingValue = "true")
public class SessionTimeoutInterceptor extends BaseController {

    @Pointcut("execution(* com.victor.*..controller.*.*(..))")
    public void cutService() {
    }

    @Around("cutService()")
    public Object sessionTimeoutValidate(ProceedingJoinPoint point) throws Throwable {

        String servletPath = HttpKit.getRequest().getServletPath();
        //忽略session拦截的uri
        List<String> uriList = new ArrayList<>();
        uriList.add("/" + Const.FILE_PREFIX);//文件
        uriList.add(Magic.URI_KAPTCHA);
        uriList.add(Magic.URI_LOGIN);
        uriList.add("/global/error");
        uriList.add("/error");
        uriList.add(Magic.URI_GLOBAL_SESSIONERROR);
        boolean flag = false;
        for (Iterator<String> it = uriList.iterator(); it.hasNext(); ) {
            String uri = it.next();
            if (ToolUtil.regex(uri + "((/.*?)|(\\?.*?))?", servletPath)) {
                flag = true;
                break;
            }
        }

        if (flag) {
            return point.proceed();
        } else {
            if (ShiroKit.getSession().getAttribute(Magic.SESSION_FLAG) == null) {
                ShiroKit.getSubject().logout();
                throw new InvalidSessionException();
            } else {
                //如果用户登入后  账号被冻结  用户执行任何操作后 都会被踢出
                User user = ConstantFactory.me().getUserById(ShiroKit.getUser().getId());
                if (ToolUtil.isEmpty(user) || !user.getStatus().equals(ManagerStatus.OK.getCode())) {
                    ShiroKit.getSubject().logout();
                    throw new DisabledAccountException();
                } else {
                    return point.proceed();
                }
            }
        }
    }
}
